最早记录元程序的例子是Erwin Unruh，当时他在C++标准化委员会中作为西门子的代表。他注意到模板实例化过程的计算完整性，并通过开发第一个元程序证明了他的观点。他使用Metaware编译器并诱导它发出包含连续素数的错误消息。以下是在1994年C++委员会会议上流传的代码(经过修改，现在可以在符合标准的编译器上编译):

\hspace*{\fill} \\ %插入空行
\noindent
\textit{meta/unruh.cpp}
\begin{lstlisting}[style=styleCXX]
// prime number computation
// (modified from original from 1994 by Erwin Unruh)

template<int p, int i>
struct is_prime {
	enum { pri = (p==2) || ((p%i) && is_prime<(i>2?p:0),i-1>::pri) };
};

template<>
struct is_prime<0,0> {
	enum {pri=1};
};

template<>
struct is_prime<0,1> {
	enum {pri=1};
};

template<int i>
struct D {
	D(void*);
};

template<int i>
struct CondNull {
	static int const value = i;
};
template<>
struct CondNull<0> {
	static void* value;
};
void* CondNull<0>::value = 0;

template<int i>
struct Prime_print { // primary template for loop to print prime numbers
	Prime_print<i-1> a;
	enum { pri = is_prime<i,i-1>::pri };
	void f() {
		D<i> d = CondNull<pri ? 1 : 0>::value; // 1 is an error, 0 is fine
		a.f();
	}
};

template<>
struct Prime_print<1> { // full specialization to end the loop
	enum {pri=0};
	void f() {
		D<1> d = 0;
	};
};

#ifndef LAST
#define LAST 18
#endif

int main()
{
	Prime_print<LAST> a;
	a.f();
}
\end{lstlisting}

若编译这个程序，当在Prime\_print::f()中，d的初始化失败时，编译器将打印错误消息。当初始值为1时就会发生这种情况，因为只有void*的构造函数，只有0有到void*的有效转换。在某个编译器上，我们得到(其他几个消息中)以下错误信息:

{\footnotesize
\begin{tcblisting}{commandshell={}}
unruh.cpp:39:14: error: no viable conversion from ’const int’ to ’D<17>’
unruh.cpp:39:14: error: no viable conversion from ’const int’ to ’D<13>’
unruh.cpp:39:14: error: no viable conversion from ’const int’ to ’D<11>’
unruh.cpp:39:14: error: no viable conversion from ’const int’ to ’D<7>’
unruh.cpp:39:14: error: no viable conversion from ’const int’ to ’D<5>’
unruh.cpp:39:14: error: no viable conversion from ’const int’ to ’D<3>’
unruh.cpp:39:14: error: no viable conversion from ’const int’ to ’D<2>’
\end{tcblisting}
}

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}由于编译器中的错误处理不同，有些编译器可能会在打印第一个错误消息后停止。
\end{tcolorbox}

C++模板元编程作为一种编程工具的概念，是由Todd Veldhuizen在他使用C++模板元程序的论文(参见[VeldhuizenMeta95])中首次发表(并在某种程度上形式化)的。Todd在Blitz++(C++的数字数组库，参见[Blitz++])方面的工作还对元编程(以及表达式模板技术，在第27章中介绍)进行了许多改进和扩展。

本书的第一版和Andrei Alexandrescu的《现代C++设计》(参见[AlexandrescuDesign])通过对至今仍在使用的基本技术进行编码，促进了利用基于模板的元编程的C++库的爆火(Boost项目(参见[Boost])控制了这次爆火的场面)。早期的这些技术引入了MPL(元编程库)，为类型元编程定义了一致的框架，这种框架也通过Abrahams和Gurtovoy的书《C++模板元编程》(参见[BoostMPL])而流行起来。

Louis Dionne在使元编程在语法上更容易访问方面取得了其他重要进展，特别是通过他的Boost.Hana库(参见[boostana])。Louis和Andrew Sutton、Herb Sutter、David Vandevoorde等人现在正在标准化委员会中努力，为语言使用元编程提供一流的支持。这项工作的一个重要基础是探索哪些程序属性应该通过反射可用;Mat\'{u}\v{s}\ Chochl\'{i}k, Axel Naumann和David Sankel是该领域的主要贡献者。

John J. Barton和Lee R. Nackman在[BartonNackman]中说明了在执行计算时如何跟踪维度单位。SIunits库是一个更全面的库，用于处理Walter Brown开发的物理单元。标准库中的std::chrono组件(我们使用它作为第23.1.4节的灵感来源)只处理时间和日期，由Howard Hinnant贡献。






























